package XMFramework.Core
{
	import XMFramework.Core.Events.SEvent;
	import XMFramework.Interface.IEventDispatcher;
	
	import flash.events.EventDispatcher;
	
	public class SEventDispatcher implements IEventDispatcher
	{
		private var listenTable:Array;
		private var dispatcher:EventDispatcher;
		
		public function SEventDispatcher()
		{
			listenTable	=	new Array();
			dispatcher	=	new EventDispatcher();	
		}
		
		public function dispatchEvent( type:String, bubbles:Boolean, cancelable:Boolean, ...params ):void
		{
			var eObj:SEvent		=	new SEvent( type, bubbles, cancelable, params );
			dispatcher.dispatchEvent( eObj );
		}
		
		public function clearAllListener():void
		{
			for( var i:String in listenTable )
			{
				var l:Object	=	listenTable[i];
				dispatcher.removeEventListener( l.type, l.func, l.capture );
			}
		}
		
		public function addEventListener( type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{			
			var ld:Object;
			
			// Check exist same listener 
			for( var i:String in listenTable )
			{
				ld		=	listenTable[i];
				if( ld.type == type && ld.func == listener && ld.capture == useCapture )
					return;				
			}
			
			// Mark listener for later use
			ld			=	new Object();
			ld.type		=	type;
			ld.func		=	listener;
			ld.capture	=	useCapture;
			listenTable.push( ld );
			
			dispatcher.addEventListener( type, listener, useCapture, priority, useWeakReference );
		}
		
		public function removeEventListener( type:String, listener:Function, useCapture:Boolean=false):void
		{
			// Clear exist listener in table data
			for( var i:String in listenTable )
			{
				var ld:Object	=	listenTable[i];
				if( ld.type == type && ld.func == listener && ld.capture == useCapture )					
				{
					listenTable.splice( i, 1 );
					break;
				}
			}
			
			dispatcher.removeEventListener( type, listener, useCapture );
		}
		
		public function hasEventListener( type:String ):Boolean
		{
			return dispatcher.hasEventListener( type );
		}
		
		internal function directAddEventListener( type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			dispatcher.addEventListener( type, listener, useCapture, priority, useWeakReference );
		}
	}
}